#include "Arduino.h"
#include "StraightKey.h"

#define STRAIGHT_PIN 12
unsigned short key_down = 0;
unsigned int word_gap = 0;
unsigned int letter_gap = 0;
extern Buzzer buzzer;
extern MorseUtils morse;
extern UI ui;
extern unsigned long dit_tm;
unsigned long last_tm = 0;
int timepoint()
{
    unsigned long t = millis();
    int td = (int)(t - last_tm);
    last_tm = t;
    return td;
}
static unsigned int pr_his = 0;
bool countSetBits(int n, int t)
{
    // `count` stores the total bits set in `n`
    int count = 0;
 
    while (n)
    {
        n = n & (n - 1);    // clear the least significant bit set
        count++;
        if (count >= t) {
            return true;
        }
    }
 
    return false;
}
//void 
void straight_run()
{
    // 记录状态历史，用于消抖
    
    int key_state = digitalRead(STRAIGHT_PIN);
    pr_his = (pr_his << 1) | (!key_state);
    //Serial.println(key_state);
    //Serial.printf("state is %d \r\n", key_state);
    // 最近7次有LOW则按下
    if (countSetBits((pr_his & 4095), 5))
    {
        //Serial.printf("state is %d his is %d val is %d \r\n", key_state, pr_his, (pr_his & 7));
        // 已经按键处理则忽略
        if (key_down != 1)
        {
            key_down = 1;
            //Serial.println("keydowning");
            int gap = timepoint();
            do_press();
            // 按下标记
            
        }
    }
    // Key up
    else if (key_down == 1)
    {
        //Serial.printf("state is %d his is %d val is %d\r\n", key_state, pr_his, (pr_his & 7));
        //Serial.println("keyuping");
        key_down = 0;
        int keyed = timepoint();
        // 关闭 Buzzer
        do_release();
        

        if (keyed < (dit_tm * 2))
        {
            morse.FireDit();
        }
        else
        {
            morse.FireDah();
        }
    }
    else if (key_down == 0)
    {
        //Serial.println("keyuped");
        unsigned long tm = millis();
        unsigned long gap = (tm - last_tm);
        //Serial.printf("last_tm is %d gap is %d\n", last_tm, gap);
        if (gap > dit_tm * 3)
        {
            // todo
            char c = morse.GetRst();
            if (c != 0)
            {
                ui.fire_char(c);
            }
            if (gap > dit_tm * 7)
            {
                // todo
                ui.fire_char(' ');
                key_down = -1;
            }
        }
    }
    vTaskDelay(1 / portTICK_PERIOD_MS);
}

void do_press()
{
    buzzer.beep();
    //digitalWrite(BUZZER_PIN, HIGH);
    // Mouse.press();
}
void do_release()
{
    buzzer.stop();
    //digitalWrite(BUZZER_PIN, LOW);
    // Mouse.release();
}